From c72528e6beafc77f764c6c2a31573d372f2872e7 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Thu, 1 Sep 2005 10:38:57 +0000 Subject: [PATCH] Hook up sysrq for xencons. Having sysrq is regularly handy. Following in the tradition set by the various consoles for virtual ppc stuff, the sysrq key is ^O. Signed-off-by: Jeremy Katz Signed-off-by: Christian Limpach --- .../drivers/xen/console/console.c | 29 +++++++++++++++++-- .../drivers/xen/console/xencons_ring.c | 2 +- .../drivers/xen/console/xencons_ring.h | 3 +- 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/console/console.c b/linux-2.6-xen-sparse/drivers/xen/console/console.c index 432f15594e..f19dd485e3 100644 --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -66,6 +67,11 @@ static enum { XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL } xc_mode = XC_DEFAULT; static int xc_num = -1; +#ifdef CONFIG_MAGIC_SYSRQ +static unsigned long sysrq_requested; +extern int sysrq_enabled; +#endif + static int __init xencons_setup(char *str) { char *q; @@ -296,7 +302,7 @@ static int xencons_priv_irq; static char x_char; /* Non-privileged receive callback. */ -static void xencons_rx(char *buf, unsigned len) +static void xencons_rx(char *buf, unsigned len, struct pt_regs *regs) { int i; unsigned long flags; @@ -304,8 +310,27 @@ static void xencons_rx(char *buf, unsigned len) spin_lock_irqsave(&xencons_lock, flags); if ( xencons_tty != NULL ) { - for ( i = 0; i < len; i++ ) + for ( i = 0; i < len; i++ ) { +#ifdef CONFIG_MAGIC_SYSRQ + if (sysrq_enabled) { + if (buf[i] == '\x0f') { /* ^O */ + sysrq_requested = jiffies; + continue; /* don't print the sysrq key */ + } else if (sysrq_requested) { + unsigned long sysrq_timeout = sysrq_requested + HZ*2; + sysrq_requested = 0; + /* if it's been less than a timeout, do the sysrq */ + if (time_before(jiffies, sysrq_timeout)) { + spin_unlock_irqrestore(&xencons_lock, flags); + handle_sysrq(buf[i], regs, xencons_tty); + spin_lock_irqsave(&xencons_lock, flags); + continue; + } + } + } +#endif tty_insert_flip_char(xencons_tty, buf[i], 0); + } tty_flip_buffer_push(xencons_tty); } spin_unlock_irqrestore(&xencons_lock, flags); diff --git a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c index 889a6a3ac1..2499d80352 100644 --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c @@ -82,7 +82,7 @@ static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs) while (ring->cons < ring->prod) { if (xencons_receiver != NULL) { xencons_receiver(ring->buf + XENCONS_IDX(ring->cons), - 1); + 1, regs); } ring->cons++; } diff --git a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h index be6e76cba8..2b91fba968 100644 --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.h @@ -7,7 +7,8 @@ asmlinkage int xprintk(const char *fmt, ...); int xencons_ring_init(void); int xencons_ring_send(const char *data, unsigned len); -typedef void (xencons_receiver_func)(char *buf, unsigned len); +typedef void (xencons_receiver_func)(char *buf, unsigned len, + struct pt_regs *regs); void xencons_ring_register_receiver(xencons_receiver_func *f); #endif /* _XENCONS_RING_H */ -- 2.30.2